import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.OAEPParameterSpec;
import javax.crypto.spec.PSource;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;
import java.util.*;

/**
 * 数美SDK深度分析器
 * 
 * 核心推断：
 * 1. ep 字段可能不包含密钥，而是签名或校验信息
 * 2. AES 密钥可能是硬编码的，或者从特定算法派生
 * 3. 需要分析 data 字段的前16字节是否是 IV
 */
public class ShumeiAnalyzer {
    
    private static final String CERTIFICATE_BASE64 = 
        "MIIC6DCCadCgAwIBAgIGAZlhQblOMA0GCSqGSIb3DQEBCwUAMDUxCzAJBgNVBAYTAkNOMRAwDgYDVQQKEwdFeGFtcGxlMRQwEgYDVQQDEwtTZWxmLVNpZ25lZDAeFw0yNTA5MTkwOTE1MjFaFw0yNjA5MTkwOTE1MjFaMDUxCzAJBgNVBAYTAkNOMRAwDgYDVQQKEwdFeGFtcGxlMRQwEgYDVQQDEwtTZWxmLVNpZ25lZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALPwnK6bMFFHWeN3E/MIWmpZesBQGILjJxNtMN1Z2lmRyLCJdTmz87EXmLuX4e/Bz0aCOmH88qjs+laHFmnPIQal3rJU32MCMk63bejZN6yArwv8MAyF0kvyA3EoBC6ZsYX55sxtxLyNYvG8MCqmacRbxV0IsSMXq6o4+1wOYiQEXzdbqhp67fYPNOv81LXqxQZArGV+Wj2o86XtW1wixtHnaSUori4jJjbe1YKi6LIbzhz9SK34+V4PkRhQYS7ensgAAbm4k3N5R3RSNkOHLrHu576QaBwKYI1DjNJL9tAcySdqXColS9RLG0h/x2r78Pvybt3hm32f1kPbu3hnaMcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEApMy1ilW+EsqQZ+2VMyvmQgjfqoaat5kvNqdluLwtzISuY/dv1V2ccR3eShnta7hKO1WCT1WF3L31MLtDwWw/VEiWFDu3+H/9P9nWr7w6ocGVWCUwUoZwiJk5DuBKZYlmj8LgjAKk6bh3hi7Fs3Kbct1rLXUtL0wiqRF7y49tnjWKiEOzgIeHQnS6m2geS1aEpUQlsEm8vUanNuAmnWJppMpfJuWQ7XDPZfRDelyepkefWSdOtd3RKKWGhk70KM00Scmav4mrUYE1K8xIXUvYrc2ECpyvuJjZ6masXzoTRGN+bEvlOML/U6TTbXIttbqqnNe9iLrszUStBXjGkpJohA==";
    
    private static final String PRIVATE_KEY_PEM = 
        "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCz8JyumzBRR1njdxPzCFpqWXrAUBiC4ycTbTDdWdpZkciwiXU5s/OxF5i7l+Hvwc9Ggjph/PKo7PpWhxZpzyEGpd6yVN9jAjJOt23o2TesgK8L/DAMhdJL8gNxKAQumbGF+ebMbcS8jWLxvDAqpmnEW8VdCLEjF6uqOPtcDmIkBF83W6oaeu32DzTr/NS16sUGQKxlflo9qPOl7VtcIsbR52klKK4uIyY23tWCouiyG84c/Uit+PleD5EYUGEu3p7IAAG5uJNzeUd0UjZDhy6x7ue+kGgcCmCNQ4zSS/bQHMknalwqJUvUSxtIf8dq+/D78m7d4Zt9n9ZD27t4Z2jHAgMBAAECggEAAr15RVdrpvE1NzeLADpyVghCzEbr+KJI6AzTn6tMneyQZ8/QDy7kWSAI3WJ0uFf1Nhepl/BoKZZiQYsRFk9nK1i/SWvtcu6HoZc9fzw/ksrq333ZpXcsOqfW0ZRQa/0/LNEfaKGLS2vDw/afrSaXmbvkB4SoXeZwYMk5Wq+FYxL/alrNpg/lzdvBlsCsTDA0G2RZrUVaO5yRTLRisBU+i8yORgnGkEwWvKpZYSFogCHSiYHiNXFy//C+sYWlK7DjmG8/+krKhqBRRfdeg7LFThHQpbEGTtueD57jw0PCo2yr6dqTvW9Qys+aWVNJk7RHNaI0yBFKWPadaHi3/olzkQKBgQDmz/FDpztS0fjKDIOjgDyE76Z6dRFenmKJM1eOFt+MniY6/vi4ylU51/Etm4k6dNJ1MVBoFfyT9X0U/4k7GNNUfIxMCJztUgY6EaCCt+09wk8pIvmOlRCmtxGwvmVC4nJVgUj3XJQ+wseblAkkW0+IuT3GKX0CdKFMU4q9aucLYwKBgQDHk3rQ8Ae4ci4oj+MehRI29SNpcXG6OHbrZ2EdsgqiFC1o/qv0269jtmCP7IqkGMdhTQrVetTHjZNZJH2bvUZ4o/0YT2+TTFPIkTb2/a0txUTBTKrbnAdXh/iPFZAGvBROEDN0MNKo/vGAfi0K836DeTyBIaYongm66Rn6pwnUTQKBgBveVaougfoxAhIbSrWuISCH8xjsE6nSA+G/Aj5Uwq8u1TzgVlWxkHLIgQVZt0sImfSufJ/kr7eJt42WgRJSoAmedC4mCBSbh8bxI+lEne+MC5TS9UDi/Ly0c/1cL8vQna93ScEcO4YMbJ97U1NBdyvx+eR4U/C89lDJ8YGHa9gzAoGAQ6sYsHFCXOKyDeTDoFyEUYgKqrzhT7/HaofR4Oy2OEBZKUl4anx2WnvC/+m3FG6mY7JoovuT29mABXCe+khR9aO8tBpy/WGa4t2B4nse1e8WIehp4i5kOuSKfZFVFUN+Kv3JRHMtakmO/v9JLHZlBhT8U9hh61GygOJ6gYdTiN0CgYAFz9iPy/xqLOUwiTNp3ImzhdZo9ol3Qlr9CfMWMFHqRA5AyYvly9ZzxTpUCpSA+qz6OXqAjJ0bhGQxW2KHpmcTyNGOPPca2vCaW8Mb1NTQueXpUBqX7alIkrRjUUyULteLb8FtyYl7mR3TVIu3FoO5anNwDZ+2y7R9WUEiOzY3NA==";
    
    private static final String ORGANIZATION = "qvdTr7A9k1DIU04ha4eP";
    private static final String APP_ID = "default";
    private static final long TIMESTAMP = 1761287286183L;
    
    private static final String EP_ENCRYPTED = 
        "qt0AJsNLEfayUx7S15jLfmQvMOpW6JJ+jCoxeXxn676R2OiN6xpLIQWSYe8ETFUF4+AaGrVY1wMCdyUPVaHM0J+8m+q/PUFgbiP3N8xSKQc4lIzzZuckbybYiFuLbEhcblmy162S5B70UJxzB6grhIVpsG/h0uw+JPaS2yTPpPVCiN/SImdOw2g12cun6niAwRZSQktZikzzbjwkRoiO8ehrwlAFJircnT1/1zba2oaGXLc/yU6cM2vWgJdyyoXJF4Mo/5XNBTDT+8yr1hPC5MKHWcTBB/isrRTD5CczInLgXHl48KKz18GkpPM7MML1GHb4pIjfTvu8hv/SLLW0sg==";
    
    private static final String TN_ENCRYPTED = 
        "BMWDCPVx97y8KsnGiff6u4lmEogvgO30LtR/QvfGyqQWadycCGkbGhL7jCKvJTHmlK0k+fDR0XKq8U2IINpo0+aiWg8+nwaXQofOsilfXgDzG0DK9WJuwfcOrzGUHBn4yGVXDj+SUklPWbq0fojYGLYendkSnSLYTzeYIusMyZ3HD2djXyUvekKz0cp39JgrD/Ovj2Nrwn4ffPHcIXgSjpd02QXn4LNb4/7q465mfS2oQ5fRqiRMcnxpUhSD3Ty15bXVKJpPVqlqpM+tcUcXVV4g7ggOux361BsPius8as1vd7wuK44EOJ56MJeATqROjECur2bWdftoWydjfZj5sw==";
    
    private static final String DATA_ENCRYPTED = 
        "wHBy2LDIay6WCgEybO8bw/5OxmVd4N++OJpwr/Tgjw+TA8iZ4HAy4bN8UWtwmeGz+dqU/zX6myCireq+q465rqUqpXLhma2aEPqTaNvUTv/Y71kVpkMBkgrjMnVkIi/iBV5eKsrTPfLWO8bt0mSbLM8ghswC2m2YRInkqWXHrc8Nw0JsNjwCllOUdtwe3NuIx8oQuQ2fqj1G3g3xMp6B4sWBNAo+SjTNuKnS4chvbaD3RYnGvSLyNYu+sqbKeRNofCwVn0lVrjCAGtC9d5nqhFiGw0vWksPfmCRn7vRsl7LnqcXb+Fal/hhREBsaRJdMrst3vOEeQI6pt3RGKZ3VOsliNziKbLiNnXp2zY2fin32okAFwIOczPgeQA1yAM4FCnuT9FYAMn5ecAOY7WFhJPcOqVThy0giCJrBzpIzEHXTin+BWBO1PR8wMzBqpf6us9mhBZGzu40mzVN34xXK646aMr8f2DcD9yGO20v5icEz3OUcAeayMq+YKmBoypmvQUnaGa8pjr7RfvvajY+7pu6QHqRAQ3NLY1KjIoT3PKjabb7owQ1Txw5+Ajfjen7VEeF/Dq03nPMtNOpqD3tCdWDHWir+akJcEPtPzK4Bo2K3FrLBZt2igZD6/04jtwoAojHibKqUM1Rj5h2iijH65eAU1XKTpqDPNtcP5lwa1bFNV+GvuzHM+N4gcoxiELhQeG7xiUcsZrJvadkDO2z+If9vLkXTSdMKrqozUjLRapyXpULcVL8negHnj+2vKZVdoGiDhXlm23XDFjLY91ZqX2eGfGNmpJxftl83N6q4dyXpzD2gR/chHfm0CukVlL8P8aPAfEDcAsyQETc5oVLzetGVSkGBbQl+axZu8U2Ap9CXaTi1b2VcI3he19nvgG8XEFnwP6Tbicm5PDDsiRjo2MRqfuPLWkcSHTmBlS6w8yrzAvth9x/bBLg8XLs8M/B/dKSfOa9sbptfTMmEuuhWbnqCyqnFSUt8lsFlcUbJdK02TcMbd789pANnrKTTfFeOUehu5XReHng4DfV7f6boQmJPnZfwuR8qFwp7vwme235RTloktlkQu/2QFl2LmCv+/8Za43dEdFba9Ae6I1p+50zunyIjGTE6/9RT+g/zgagzgV/qDDSM5VF6E2Ic62W/KkpfSPMHAk5Jwg0LlsSMnFXYCynZoDZ5M8s62V15VaEII3s/6wPCu4lba/BxPanRtw60EVsvrJ7B0mnG+hcW8AGVeG1ZBIhgPH887/bY+05b0MnSkhjlrys8GKSaukVbtnrLJmjePt+LdLe6tH2NTwxjbHhJR028ZWaQKvdC5BD2hRflDMBPKL68D6YJ2bitqnKKdEqYHdCMXtOXh68XUqwfkoF3phQtYHyrqF4Wsgukf3/gAlt/yF0dXFTIUzoDTc34MEAaLFENVFDt4PUnYw2SRT8i/bhi3tcavu6Hnjs=";
    
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
    
    /**
     * 新假设：data 的前16字节可能就是 IV
     */
    private static void analyzeDataStructure() {
        System.out.println("\n" + "=".repeat(80));
        System.out.println("新假设：data 字段的前16字节可能是 IV");
        System.out.println("=".repeat(80));
        
        try {
            byte[] dataBytes = Base64.getDecoder().decode(DATA_ENCRYPTED);
            
            // 提取前16字节作为可能的IV
            byte[] possibleIv = Arrays.copyOf(dataBytes, 16);
            byte[] actualData = Arrays.copyOfRange(dataBytes, 16, dataBytes.length);
            
            System.out.println("data 前16字节（可能是IV）:");
            System.out.println("  " + bytesToHex(possibleIv));
            System.out.println("\n实际加密数据:");
            System.out.println("  长度: " + actualData.length + " 字节");
            System.out.println("  前32字节: " + bytesToHex(Arrays.copyOf(actualData, Math.min(32, actualData.length))));
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 新假设：尝试不同的 RSA 填充模式
     */
    private static void tryDifferentRSAPaddings() {
        System.out.println("\n" + "=".repeat(80));
        System.out.println("尝试不同的 RSA 填充模式");
        System.out.println("=".repeat(80));
        
        try {
            byte[] epBytes = Base64.getDecoder().decode(EP_ENCRYPTED);
            byte[] privateKeyBytes = Base64.getDecoder().decode(PRIVATE_KEY_PEM);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            
            // 尝试不同的填充模式
            String[] paddings = {
                "RSA/ECB/PKCS1Padding",      // 标准
                "RSA/ECB/OAEPWithSHA-1AndMGF1Padding",  // OAEP + SHA1
                "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", // OAEP + SHA256
                "RSA/ECB/NoPadding"          // 无填充
            };
            
            for (String padding : paddings) {
                try {
                    System.out.println("\n尝试: " + padding);
                    Cipher cipher = Cipher.getInstance(padding);
                    cipher.init(Cipher.DECRYPT_MODE, privateKey);
                    byte[] decrypted = cipher.doFinal(epBytes);
                    
                    System.out.println("✅ 解密成功！");
                    System.out.println("解密长度: " + decrypted.length + " 字节");
                    System.out.println("十六进制: " + bytesToHex(decrypted));
                    
                    // 尝试解析为文本
                    try {
                        String text = new String(decrypted, StandardCharsets.UTF_8);
                        System.out.println("文本内容: " + text);
                    } catch (Exception e) {
                        System.out.println("无法解析为UTF-8文本");
                    }
                    
                    return; // 成功就退出
                } catch (Exception e) {
                    System.out.println("❌ 失败: " + e.getMessage());
                }
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 新假设：密钥可能是固定的常见值
     */
    private static void tryCommonKeys() {
        System.out.println("\n" + "=".repeat(80));
        System.out.println("尝试常见的硬编码密钥");
        System.out.println("=".repeat(80));
        
        try {
            byte[] dataBytes = Base64.getDecoder().decode(DATA_ENCRYPTED);
            
            // 常见的硬编码密钥
            String[] commonKeys = {
                "0123456789abcdef0123456789abcdef", // 简单测试密钥
                "00000000000000000000000000000000", // 全零
                "ffffffffffffffffffffffffffffffff", // 全1
                "shumei_sdk_key_v1_default_value!", // 可能的数美密钥
                "qvdTr7A9k1DIU04ha4ePdefaultkey!!", // org+appId组合
            };
            
            String[] commonIvs = {
                "0123456789abcdef",
                "0000000000000000",
                "ffffffffffffffff",
                "shumei_init_vec",  // 可能的数美IV
            };
            
            for (String keyHex : commonKeys) {
                byte[] key;
                if (keyHex.length() == 32) {
                    // 尝试直接解析
                    try {
                        key = hexToBytes(keyHex);
                    } catch (Exception e) {
                        // 如果不是十六进制，就直接用UTF-8
                        key = Arrays.copyOf(keyHex.getBytes(StandardCharsets.UTF_8), 32);
                    }
                } else {
                    key = Arrays.copyOf(keyHex.getBytes(StandardCharsets.UTF_8), 32);
                }
                
                for (String ivHex : commonIvs) {
                    byte[] iv;
                    if (ivHex.length() == 16) {
                        try {
                            iv = hexToBytes(ivHex);
                        } catch (Exception e) {
                            iv = Arrays.copyOf(ivHex.getBytes(StandardCharsets.UTF_8), 16);
                        }
                    } else {
                        iv = Arrays.copyOf(ivHex.getBytes(StandardCharsets.UTF_8), 16);
                    }
                    
                    try {
                        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
                        IvParameterSpec ivSpec = new IvParameterSpec(iv);
                        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
                        byte[] decrypted = cipher.doFinal(dataBytes);
                        
                        // 尝试解压
                        try {
                            java.util.zip.Inflater inflater = new java.util.zip.Inflater(true);
                            inflater.setInput(decrypted);
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            byte[] buffer = new byte[1024];
                            while (!inflater.finished()) {
                                int count = inflater.inflate(buffer);
                                baos.write(buffer, 0, count);
                            }
                            byte[] decompressed = baos.toByteArray();
                            String result = new String(decompressed, StandardCharsets.UTF_8);
                            
                            if (result.length() > 10 && result.contains("{")) {
                                System.out.println("\n✅ 可能找到了！");
                                System.out.println("密钥: " + keyHex);
                                System.out.println("IV: " + ivHex);
                                System.out.println("解密内容: " + result);
                                return;
                            }
                        } catch (Exception e) {
                            // 解压失败，继续
                        }
                    } catch (Exception e) {
                        // 解密失败，继续
                    }
                }
            }
            
            System.out.println("❌ 未找到匹配的常见密钥");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private static byte[] hexToBytes(String hex) {
        int len = hex.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                                 + Character.digit(hex.charAt(i+1), 16));
        }
        return data;
    }
    
    /**
     * 新假设：IV 可能包含在密文的前16字节
     */
    private static void tryIvPrependedMode() {
        System.out.println("\n" + "=".repeat(80));
        System.out.println("新假设：IV 包含在密文前16字节（常见模式）");
        System.out.println("=".repeat(80));
        
        try {
            byte[] dataBytes = Base64.getDecoder().decode(DATA_ENCRYPTED);
            
            // 提取前16字节作为IV
            byte[] iv = Arrays.copyOf(dataBytes, 16);
            byte[] ciphertext = Arrays.copyOfRange(dataBytes, 16, dataBytes.length);
            
            System.out.println("提取的IV: " + bytesToHex(iv));
            System.out.println("密文长度: " + ciphertext.length);
            
            // 尝试从证书派生密钥
            byte[] certBytes = Base64.getDecoder().decode(CERTIFICATE_BASE64);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(
                new ByteArrayInputStream(certBytes));
            
            // 尝试多种密钥派生方式
            MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
            
            List<byte[]> keys = new ArrayList<>();
            keys.add(sha256.digest(cert.getPublicKey().getEncoded()));
            keys.add(sha256.digest((ORGANIZATION + ":" + APP_ID).getBytes(StandardCharsets.UTF_8)));
            keys.add(sha256.digest(ORGANIZATION.getBytes(StandardCharsets.UTF_8)));
            
            for (int i = 0; i < keys.size(); i++) {
                try {
                    SecretKeySpec keySpec = new SecretKeySpec(keys.get(i), "AES");
                    IvParameterSpec ivSpec = new IvParameterSpec(iv);
                    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                    cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
                    byte[] decrypted = cipher.doFinal(ciphertext);
                    
                    // 解压
                    java.util.zip.Inflater inflater = new java.util.zip.Inflater(true);
                    inflater.setInput(decrypted);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1024];
                    while (!inflater.finished()) {
                        int count = inflater.inflate(buffer);
                        baos.write(buffer, 0, count);
                    }
                    byte[] decompressed = baos.toByteArray();
                    String result = new String(decompressed, StandardCharsets.UTF_8);
                    
                    if (result.length() > 10 && result.contains("{")) {
                        System.out.println("\n✅ 成功解密！（密钥方案 " + (i+1) + "）");
                        System.out.println("密钥: " + bytesToHex(keys.get(i)));
                        System.out.println("IV: " + bytesToHex(iv));
                        System.out.println("\n解密内容:");
                        System.out.println(result);
                        return;
                    }
                } catch (Exception e) {
                    // 继续尝试
                }
            }
            
            System.out.println("❌ 未能解密");
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        System.out.println("=".repeat(80));
        System.out.println("数美SDK深度分析器");
        System.out.println("=".repeat(80));
        
        // 1. 分析 data 结构
        analyzeDataStructure();
        
        // 2. 尝试不同的 RSA 填充模式
        tryDifferentRSAPaddings();
        
        // 3. 尝试常见的硬编码密钥
        tryCommonKeys();
        
        // 4. 尝试 IV 前置模式（最常见）
        tryIvPrependedMode();
        
        System.out.println("\n" + "=".repeat(80));
        System.out.println("分析完成");
        System.out.println("=".repeat(80));
    }
}



